package com.sdy.healthcode.web.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.integration.redis.util.RedisLockRegistry;

/**
 * Spring Data Redis配置
 * Created by zzq on 2019/1/11.
 */
@Configuration
@PropertySource("file:/opt/config/healthcode_child/redisConfig.properties")
@ComponentScan({"com.sdy.redis.service", "com.sdy.redis.driver"})
public class RedisConfig {
    @Value("${redis.host}")
    private String host;

    @Value("${redis.port}")
    private int port;

    @Value("${redis.password:}")
    private String password;

    /**
     * LettuceConnectionFactory 据说jedis多线程访问会有问题，所以这里用LettuceConnectionFactory
     *
     * @return LettuceConnectionFactory
     */
    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(host, port);
        config.setPassword(password);
        return new LettuceConnectionFactory(config);
    }

    /**
     * 获取RedisTemplate
     *
     * @param connectionFactory RedisConnectionFactory
     * @return RedisTemplate
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        // 关闭redis事务
        template.setEnableTransactionSupport(false);
        /*
         * 设置redis序列化工具
         * GenericJackson2JsonRedisSerializer 序列化成json的时候会带上类信息
         * Jackson2JsonRedisSerializer 直接序列化成json，这个在序列化带long类型的hashmap的时候，反序列化的类型就无法区分是long还是int
         * @see <a href="https://docs.spring.io/spring-data/redis/docs/2.1.4.RELEASE/reference/html/">Spring Data Redis</a>
         */
        GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
        template.setKeySerializer(StringRedisSerializer.UTF_8);
        template.setHashKeySerializer(StringRedisSerializer.UTF_8);
        template.setValueSerializer(serializer);
        template.setHashValueSerializer(serializer);
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory) {
        return new RedisLockRegistry(redisConnectionFactory, "spring-cloud-distributed-lock", 300 * 1000L);
    }
}
